#!/usr/python3.6.3/bin/python3
# -*- coding: utf-8 -*-
import subprocess
import requests
import sys
import os


class Ts:
    """检测工具类"""

    @staticmethod
    def testurl(url):
        """
        test url is return 200
        :return: utl响应码 or False
        """
        try:
            r = requests.get(url, timeout=5)
            print(url, end='')
            print('    .........   ', end='')
            print(r.status_code)
            return r.status_code
        except:
            print('服务五秒内没有响应,-_-!')
            return False

    @staticmethod
    def errorlist(stderrs, project, info):
        if stderrs:
            print("出错了!!!")
            print(stderrs)
            print('''
                 自动更新脚本出错了，我已发邮件通知运维了，
                 防止运维没有及时看到,请电话通知运维。''')
            subprocess.call('/sh/emaills.py {} {}'.format(project, info),
                            shell=True)


class BaseSvn:
    """更新基类"""
    def upd_svn(self):
        req = subprocess.Popen(
            'svn co svn://****:***/project/Release/ /usr/Release/',
            shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
        )
        # 不想输出svn拉取代码的详细信息，使用Popen
        (stdeout, stderrs) = req.communicate()
        Ts.errorlist(stderrs, 'svnerr', 'svnerr')
        # 打印svn版本号
        print(stdeout.decode('utf-8').split('\n')[-2])

    def upd_backsyscode(self, project, info, ip, configPath, configPath2,
                        shell):
        """
         系统后台 更新公共办法
        :param project: 项目名
        :param info: 报警详情
        :param ip: 正式环境IP
        :param configPath: svn chekout 的配置目录
        :param configPath2: 复制的临时文件夹目录
        :param shell: 远程机器执行的命令
        :return: None
        """
        self.upd_svn()
        # 同步到临时文件夹
        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete /**tomcatPath**/webapps/ROOT/ {}'.format(
                configPath2),
            shell=True)
        Ts.errorlist(req, project, info)

        # 替换配置文件
        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete {}application.properties  {}WEB-INF/classes/application/application.properties'.format(
                configPath, configPath2),
            shell=True)
        Ts.errorlist(req, project, info)

        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete {}index.jsp  {}index.jsp'.format(
                configPath, configPath2),
            shell=True)
        Ts.errorlist(req, project, info)

        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete {}sysparam.properties  {}WEB-INF/classes/application/sysparam.properties'.format(
                configPath, configPath2),
            shell=True)
        Ts.errorlist(req, project, info)

        # 将已处理好的临时文件下的代码推送到正式服务器
        os.system(
            '''rsync -e 'ssh -p***' -avzr --exclude '*.svn' --delete {}  root@{}:/**tomcatPath**/webapps/ROOT/'''.format(
                configPath2, ip))
        # kill tomcat ，重启 tomcat
        os.system(shell)

        # 检测
        subprocess.call(
            'ssh root@{} -p*** ps x | grep "**tomcatPath**" | grep -v "/bin/sh -c ps x"'.format(
                ip),
            shell=True)
        Ts.testurl('http://{}:***/system/login'.format(ip))
    
    def upd_merwebcode(self, project, info, ip, configPath, configPath2,
                        shell):
        """
         商户后台 更新公共办法
        :param project: 项目名
        :param info: 报警详情
        :param ip: 正式环境IP
        :param configPath: svn chekout 的配置目录
        :param configPath2: 复制的临时文件夹目录
        :param shell: 远程机器执行的命令
        :return: None
        """
        self.upd_svn()
        # 同步到临时文件夹
        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete /**tomcatPath**/webapps/ROOT/  {}'.format(configPath2),
            shell=True)
        Ts.errorlist(req, project, info)

        # 替换配置文件
        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete {}sysparam.properties {}WEB-INF/classes/application/sysparam.properties'.format(configPath, configPath2),
            shell=True)
        Ts.errorlist(req, project, info)

        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete {}application.properties {}WEB-INF/classes/application/application.properties'.format(configPath, configPath2),
            shell=True)
        Ts.errorlist(req, project, info)

        req = subprocess.call(
            'rsync  -qazr --exclude "*.svn" --delete {}profile.jsp {}WEB-INF/jsp/merchant/profile.jsp'.format(configPath, configPath2),
            shell=True)
        Ts.errorlist(req, project, info)
        # 推送
        os.system('''rsync -e 'ssh -p***' -avzr --exclude '*.svn' --delete {} root@{}:/**tomcatPath**/webapps/ROOT/'''.format(configPath2, ip))
        os.system(shell)

        subprocess.call(
                'ssh root@{} -p*** ps x | grep "**tomcatPath**" | grep -v "/bin/sh -c ps x"'.format(ip),
                shell=True)
        Ts.testurl('http://{}/system/login'.format(ip))


class AlyMerweb(BaseSvn):
    project = '正式环境-阿里云商户后台'
    info = '更新失败'
    ip = '******'
    configPath = '/usr/Release/config/new_aliyun/MerWebAdmin/'
    configPath2 = '/temporary/aliyun/new_merweb/'
    shell = '''ssh root@***** -p**** << remotessh
export JAVA_HOME=/usr/local/jdk1.7.0_80
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ps x|grep java |grep **tomcatPath**
ps x|grep java |grep **tomcatPath** |awk "{print $1}"|xargs kill -9
/**tomcatPath**/bin/startup.sh
exit
remotessh'''

    def upd_code(self):
        super().upd_merwebcode(AlyMerweb.project, AlyMerweb.info, AlyMerweb.ip,
                               AlyMerweb.configPath, AlyMerweb.configPath2,
                               AlyMerweb.shell)


class LgMerweb(BaseSvn):
    project = '正式环境-龙岗商户后台'
    info = '更新失败'
    ip = '*****'
    configPath = '/usr/Release/config/new_lg/MerWebAdmin/'
    configPath2 = '/temporary/lg/new_merweb/'
    shell = '''ssh root@***** -p**** << remotessh
export JAVA_HOME=/usr/local/jdk1.7.0_75
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ps x|grep java |grep tomcat |grep **tomcatPath**
ps x|grep java |grep tomcat |grep **tomcatPath** |awk '{print $1}' |xargs kill -9
/**tomcatPath**/bin/startup.sh
exit
remotessh'''

    def upd_code(self):
        super().upd_merwebcode(LgMerweb.project, LgMerweb.info, LgMerweb.ip,
                               LgMerweb.configPath, LgMerweb.configPath2,
                               LgMerweb.shell)


class LgBacksys(BaseSvn):
    project = '正式环境-龙岗系统后台'
    info = '更新失败'
    ip = '*******'
    configPath = '/usr/Release/config/lg/backsys/'
    configPath2 = '/temporary/lg/backsys/'
    shell = '''ssh root@***** -p***** << remotessh
export JAVA_HOME=/usr/local/jdk1.7.0_75
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ps x|grep java |grep tomcat |grep **tomcatPath**
ps x|grep java |grep tomcat |grep **tomcatPath** |awk "{print $java}"|xargs kill -9
/**tomcatPath**/bin/startup.sh
exit
remotessh'''
    
    def upd_code(self):
        super().upd_backsyscode(
            LgBacksys.project, LgBacksys.info, LgBacksys.ip, LgBacksys.configPath, LgBacksys.configPath2, LgBacksys.shell
        )


class AlyBacksys(BaseSvn):
    project = '正式环境-阿里云系统后台'
    info = '更新失败'
    configPath = '/usr/Release/config/aliyun/backsys/'
    configPath2 = '/temporary/aliyun/backsys/'
    ip = '*****'
    shell = '''ssh root@***** -p*** << remotessh
export JAVA_HOME=/usr/local/jdk1.7.0_80
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ps x|grep java |grep /**tomcatPath**/
ps x|grep java |grep /**tomcatPath**/ |awk '{print $1}' |xargs kill -9
/**tomcatPath**/bin/startup.sh
exit
remotessh'''
    
    def upd_code(self):
        super().upd_backsyscode(
            AlyBacksys.project, AlyBacksys.info, AlyBacksys.ip, AlyBacksys.configPath, AlyBacksys.configPath2, AlyBacksys.shell
        )


class SetUpdate:
    def set_values(self, values):
        self.values = values()

    def upd_code(self):
        self.values.upd_code()


if __name__ == '__main__':
    update = SetUpdate()

    if sys.argv[1] == 'Lg':
        if sys.argv[2] == 'Merweb':
            update.set_values(LgMerweb)
            update.upd_code()
        elif sys.argv[2] == 'Backsys':
            update.set_values(LgBacksys)
            update.upd_code()

    elif sys.argv[1] == 'Aliyun':
        if sys.argv[2] == 'Merweb':
            update.set_values(AlyMerweb)
            update.upd_code()
        elif sys.argv[2] == 'Backsys':
            update.set_values(AlyBacksys)
            update.upd_code()
